/**
 * @description  : 局部scrollview 
 * @descriptionDetail : 局部scrollview 
 * @copyright    : 浙江烟草
 * @author       : mc
 * @create       : 2022-10-03 17:23:51
 */
<template>
  <mescroll-uni
    :height="height"
    :top="top"
    :bottom="bottom"
    :down="downOption"
    :up="upOption"
    :ref="'mescrollRef'+i"
    @init="mescrollInit"
    @down="downCallback"
    @up="upCallback"
  >
    <view v-for="(it, idx) in listDatas" :id="getViewId(it, idx)" :key="idx">
      <slot :data="it" :index="idx"></slot>
    </view>
  </mescroll-uni>
</template>

<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import MescrollMoreItemMixin from "@/components/mescroll-uni/mixins/mescroll-more-item.js";
import MescrollUni from "@/components/mescroll-uni/mescroll-uni.vue";

export default {
  components: {
    MescrollUni,
  },
  mixins: [MescrollMixin, MescrollMoreItemMixin,],
  props: {
    i: Number, // 每个tab页的专属下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
    index: { // 当前tab的下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
      type: Number,
      default () {
        return 0
      },
    },
    height: {
      type: String,
      default: "100%",
    },
    idKey:{
      type: String,
      default:undefined,
    },
    limit:{
      type: Number,
      default: 20,
    },
    top: {
      type: String,
      default: "0",
    },
    bottom: {
      type: String,
      default: "0",
    },
    normalScrollView:{  // true 表示 通用， false 表示 上一页 下一页 当前列表保证最大limit个数据展示， 防止数据量过大造成的卡顿
      type: Boolean,
      default: true,
    },
	justScroll: { // 只需要滚动
	  type: Boolean,
	  default: false,
	},
    loadData: { // 第一个参数 page， 第二个参数 是否主动刷新数据  第三个参数 是否拼接数据(元数据页不够一页 主动拼接上一页数据)
      type: Function,
      default: function() {
        return new Promise(resolve => {
          resolve({
            totalCount: 0,
            data: [],
          });
        });
      },
    },
  }, // 注意此处还需使用MescrollMoreItemMixin (必须写在MescrollMixin后面)
  data() {
    return {
      downOption: {
        // use: this.use,
        auto: false, // 不自动加载 (mixin已处理第一个tab触发downCallback)
		use: !this.justScroll,
      },
      upOption: {
        use: !this.justScroll,
        auto: false, // 默认自动加载
        page:{
          num : 0 ,
          size : this.limit,
          time : null,
        },
        empty:{
          tip:'~没有更多数据了~',
        },
        textLoading: '加载中 ...', // 加载中的提示文本
        textNoMore: '没有更多数据了', // 没有更多数据的提示文本
        offset: 150, // 距底部多远时,触发upCallback,仅mescroll-uni生效 ( mescroll-body配置的是pages.json的 onReachBottomDistance )
        noMoreSize: 2, // 如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
      },
      listDatas: [], // 列表数据
      currentPage:1,
      needUpd:true,
    }
  },
  mounted() {
    if(this.justScroll){
      this.getData();
    }
  },
  methods: {
	getData(){
	  uni.showLoading({
	    title:'加载中...',
	  });
	  let page = {
	    num: 1,
	    size: 999,
	  };
	  this.loadData(page).then(dr => {
	    uni.hideLoading();
		this.listDatas =  [...dr.data,];
	  }, err => {
	    uni.hideKeyboard();
	    console.error(err);
	  }).catch((err) => {
	    uni.hideLoading();
	    console.error(err);
	  })
	},
    /* 下拉刷新的回调 */
    downCallback() {
      if(this.currentPage <= 1 || this.normalScrollView){
        this.mescroll.resetUpScroll()
      }else{
        this.loadData({
          num: this.currentPage - 1,
          size: this.limit,
        }, false).then(dr => {
          this.currentPage--;
          this.mescroll.setPageNum(this.currentPage + 1);
          this.listDatas =  [...dr.data,];
          this.mescroll.endBySize(dr.data.length, dr.totalCount);
        }).catch((err) => {
          console.error(err);
          this.mescroll.endErr();
        })
      }
    },
    /* 上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
    upCallback(page) {
      // 联网加载数据
      this.loadData({
        num: page.num,
        size: page.size,
      }, (page.num == 1 && this.needUpd)).then(dr => {
        this.needUpd = true;
        if(this.normalScrollView){
          this.listDatas = page.num == 1 ? [...dr.data,] : [...this.listDatas, ...dr.data,]
          this.mescroll.endBySize(dr.data.length, dr.totalCount);
        }else{
          this.currentPage = page.num;
          if(page.num == 1 || dr.data.length == page.size){
            this.listDatas = [...dr.data,];
            this.mescroll.lockUpScroll(true);
            this.mescroll.lockDownScroll(true);
            this.mescroll.endBySize(dr.data.length, dr.totalCount);
            this.scrollToTop();
          }else{
            let tmpList = this.listDatas.splice(page.size - dr.data.length);
            this.listDatas = [...tmpList, ...dr.data,];
            this.mescroll.lockUpScroll(true);
            this.mescroll.endSuccess(dr.data.length, false);
            // if(tmpList.length > 0){
            // setTimeout(() => {
            this.scrollToView(this.getViewId(tmpList[tmpList.length - 1],tmpList.length - 1), 100);
            // }, 100);
            // }
          }
        }
      }).catch((err) => {
        this.needUpd = true;
        console.error(err);
        this.mescroll.endErr();
      })
    },
    /**
	 * 对 normalScrollView 为false 时 使用。 外部需要手动改变原数据源，page需从1 重新开始
	 * @param needUpd 是否需要重新调用接口
	 */
    resetList(needUpd = true){ // 
      this.needUpd = needUpd;
      this.currentPage = 1;
      this.mescroll.triggerDownScroll();
    },
    setPageNum(num){
      if(num == this.currentPage) return false;
      this.mescroll.setPageNum(num);
      return true;
    },
    /* 上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
    toCurrentPageData(id) {
      if(this.normalScrollView) return;
      this.loadData({
        num: this.mescroll.optUp.page.num + 1,
        size: this.limit,
      }, false, true).then(dr => {
        this.currentPage = this.mescroll.optUp.page.num + 1;
        this.listDatas = [...dr.data,];
        if(dr.isSplice){
          this.mescroll.endSuccess(dr.data.length, false);
        }else{
          this.mescroll.endBySize(dr.data.length, dr.totalCount);
        }
        setTimeout(() => {
          this.scrollToViewItem(id);
        }, 100);
      }).catch((err) => {
        console.error(err);
        this.mescroll.endErr();
      })
    },
    /**
	 * 滚动到指定位置
	 */
    scrollToBottom(){
      this.mescroll.lockUpScroll(true);
      this.mescroll.scrollTo(999999, 0);
      setTimeout(() => {
        this.mescroll.lockUpScroll(false);
      }, 500);
    },
    /**
	 * 滚动到指定位置
	 */
    scrollToTop(){
      this.mescroll.scrollTo(0, 0);
      setTimeout(() => {
        this.mescroll.lockDownScroll(false);
        this.mescroll.lockUpScroll(false);
      }, 500);
    },
    getViewId(data, idx){
      if(this.idKey){
        return 'view' + data[this.idKey];
      }else{
        return 'view' + idx;
      }
    },
    scrollToView(key, t = 0){
      this.mescroll.lockUpScroll(true);
      this.mescroll.scrollTo(key, t);
      setTimeout(() => {
        this.mescroll.lockUpScroll(false);
      }, 500);
    },
    scrollToViewItem(key, t = 0){
      this.mescroll.lockUpScroll(true);
      this.mescroll.scrollTo('view' + key, t);
      setTimeout(() => {
        this.mescroll.lockUpScroll(false);
      }, 500);
    },
  },
}
</script>

<style scoped lang="scss">
/deep/.mescroll-wxs-content{
	transform: inherit !important;
}
</style>
